package ssw.game.engine;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import ssw.game.GameState;
import ssw.game.GameType;

public class GameEngine {
	private final GameType type;
	private final SortedSet<String> wordList;
	
	public GameEngine(GameType type)  {
		super();
		this.type = type;
		this.wordList = GameDictionary.makeWordList(type);
	}

	public GameState newGame()  {
		Collection<String> tiles = ComputeTiles.with(wordList, type);
		SortedSet<String> answers = computeAnswers(tiles);
		return new GameState(tiles, wordList, answers);
	}
	
	SortedSet<String> computeAnswers(Collection<String> tiles)  {
		SortedSet<String> answers = new TreeSet<String>();
		recurseAnswers("", tiles, answers);
		return answers;
	}

	void recurseAnswers(String root, Collection<String> tiles, SortedSet<String> answers) {
		if (root.length() > type.getMaxLengthOfWord())  {
			return;
		}
		else if (root.length() == type.getMaxLengthOfWord())  {
			if (wordList.contains(root))  {
				answers.add(root);
			}
		}
		else  {
			for (String letter : tiles)  {
				List<String> list = new ArrayList<String>(tiles);
				list.remove(letter);
				recurseAnswers(root + letter, list, answers);
			}
		}
	}

	public GameState submit(GameState state, SortedSet<String> guesses) {
		SortedSet<String> words = new TreeSet<String>(state.getRemainingWords());
		
		SortedSet<String> wordsToRemove = new TreeSet<String>(state.getAnswers());
		wordsToRemove.retainAll(guesses);
		
		words.removeAll(wordsToRemove);
		
		Collection<String> tiles = ComputeTiles.with(words, type);
		SortedSet<String> answers = computeAnswers(tiles);
		return new GameState(tiles, words, answers);
	}
}
